
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.js"></script>
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}

.link {
stroke: #999;
stroke-opacity: .6;
}
</style>
<body>
<script>
var json = 
{
  "nodes":[
    {
      "name":"Node1",
      "group":2
    },
    {
      "name":"Node2",
      "group":1
    },
    {
      "name":"Node3",
      "group":1
    },
     {
      "name":"Node4",
      "group":3
    }
  ],
  "links":[
    {
      "source":0,
      "target":1,
      "value":2
    },
    {
      "source":0,
      "target":2,
      "value":2
    },
     {
      "source":0,
      "target":3,
      "value":2
    }
  ]
}
;

var width = 960,
height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
    .charge(-120)
    .linkDistance(30)
    .size([width, height]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)

force.nodes(json.nodes)
	.links(json.links)
	.start();

var link = svg.selectAll(".link")
	.data(json.links)
	.enter().append("line")
	.attr("class", function(d){ return ["link", d.source.name, d.target.name].join(" "); })
	.style("stroke-width", function(d) { return Math.sqrt(d.value); });

// Find the joined nodes

//create empty object for the node info
var node2neighbors = {};

//for each of the nodes
for (var i =0; i < json.nodes.length; i++){
	
	//create a variable of its name
	var name = json.nodes[i].name;
	
	//use that name to filter out the items	
	node2neighbors[name] = json.links.filter(function(d){
			
			//get the name and if it matches the name or target
			return d.source.name == name || d.target.name == name;
	}).map(function(d){ //map it to the correspon
		return d.source.name == name ? d.target.name : d.source.name;
			
		});
}

var clickableNodes = ["Node1"];

var nodes = svg.selectAll(".node")
	.data(json.nodes)
	.enter().append("circle")
	.attr("class", "node")
	.attr("id", function(n){ return n.name; })
	.attr("r", 5)
	.style("fill", function(d) { return color(d.group); })
	.call(force.drag)

nodes.filter(function(n){ return clickableNodes.indexOf(n.name) != -1; })
    .on("click", function(n){
        // Determine if current node's neighbors and their links are visible
        var active   = n.active ? false : true // toggle whether node is active
        , newOpacity = active ? 0 : 1;

        // Extract node's name and the names of its neighbors
        var name     = n.name
        , neighbors  = node2neighbors[name];

        // Hide the neighbors and their links
        for (var i = 0; i < neighbors.length; i++){
            d3.select("circle#" + neighbors[i]).style("opacity", newOpacity);
            d3.selectAll("line." + neighbors[i]).style("opacity", newOpacity);
        }
        // Update whether or not the node is active
        n.active = active;
    });

nodes.append("title")
	.text(function(d) { return d.name; });

force.on("tick", function() {
	link.attr("x1", function(d) { return d.source.x; })
	.attr("y1", function(d) { return d.source.y; })
	.attr("x2", function(d) { return d.target.x; })
	.attr("y2", function(d) { return d.target.y; });

	nodes.attr("cx", function(d) { return d.x; })
		.attr("cy", function(d) { return d.y; });
});

</script>
</body>
</html>
